//////////////////////////////////////////////////////////////////////
//                                                                  //
//                                                                  //
//              Copyright (C), 2000  SEIKO EPSON Corp.              //
//              ALL RIGHTS RESERVED                                 //
//                                                                  //
//                                                                  //
//   file name : asin.c                                             //
//                                                                  //
//   Revision history                                               //
//       00/02/14    first release                 M.Igarashi       //
//                                                                  //
//////////////////////////////////////////////////////////////////////


#include	<math.h>
#include	<smcvals.h>

// ARGORITHM
// 1.let x to be x / sqrt( 1 - x^2 )
// 2.asin(x) = arctan( x / sqrt( 1 - x^2 ) )
//
 
//  the architecture of double floating point
//
//   0 1          11                  31 32                               63 bit
//   -----------------------------------------------------------------------
//  | |   exponent  |                    fraction                           |
//   -----------------------------------------------------------------------
//
//  |               |                   |                                   |
//  |    12 bits          20 bits       |             32 bits               |
//  |            lower word             |            higher word            |
//
//         bit    0         sign bit         (  1 bit  )
//              1 - 11      exponent part    ( 11 bits )
//             12 - 63      fraction part    ( 52 bits )
//
//
 
double asin(double dfX){

	long lX;
	unsigned long ulLx,ulHx;
	double	dfTemp;
	double dfX2,dfRet;
	
	
	GETW_L(lX,dfX);		// get low
	GETW_H(ulHx,dfX);		// get high
	CLR_SIGN( dfX2, dfX );	// clear sign
	
	ulLx = lX&0x7fffffff;

	if( ulLx > 0x3ff00000||(ulLx == 0x3ff00000 && ulHx > 0x0 )){		//check area
		errno = EDOM;
		return( NAN._D );
	}
	dfTemp=dfX2*dfX2;
	dfTemp=1.0-dfTemp;
	dfTemp = sqrt(dfTemp);
	
	if(ulLx > 0x3fe66666||(ulLx == 0x3fe66666 && ulHx > 0x66666666 ) ){	//check area
		dfTemp=dfTemp/dfX2;
		dfTemp=HLFP - atan(dfTemp);
	}else{
		dfTemp=dfX2/dfTemp;
		dfTemp=atan(dfTemp);
	}

	if( (lX&0x80000000) ==0 ){		// positive
		dfRet = dfTemp;
		return dfRet;
	}else{
		dfRet =-dfTemp;				// negative
		return dfRet;
	}

}
